package com.ds.sign.controller;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.ds.sign.config.CEB311SignSocketServer;
import com.ds.sign.config.CEB511SignSocketServer;
import com.ds.sign.config.CEB621SignSocketServer;

/**
 * @author WTZ
 * @date 2022-05-06
 */
@Controller
@RequestMapping("/api/oversea")
public class PddOverseaController
{
	@PostMapping("/dataSign")
	public @ResponseBody Object dataSign(@RequestBody JSONObject map) 
	{
		System.out.println("dataSign.start");
		
		// API接口名称
		String type = map.getString("type");
		// UNIX时间戳，单位秒
		String timestamp = map.getString("timestamp");
		// 调用方应用client_id
		String from_client_id = map.getString("from_client_id");
		// 调用目标应用的client_id
		String client_id = map.getString("client_id");
		// API输入参数签名结果，签名算法参考开放平台接入指南第三部分底部
		String sign = map.getString("sign");
		// 待签名的报关单类型
		String ceb_name = map.getString("ceb_name");
		// 企业的10位海关注册码，用于区分同一个isv的不同企业
		String base_transfer_cop_code = map.getString("base_transfer_cop_code");
		// 待签名的数据，示例为海关报文的摘要xml数据
		String data_to_sign = map.getString("data_to_sign");
		
		System.out.println("dataSign.type=" + type + 
				";from_client_id=" + from_client_id + 
				";client_id=" + client_id + 
				";sign=" + sign + 
				";ceb_name=" + ceb_name + 
				";base_transfer_cop_code=" + base_transfer_cop_code + 
				";data_to_sign=" + data_to_sign);
		
		String toDigestValue = data_to_sign;//getDigestValue(data_to_sign);
		
		System.out.println("digest_value=" + toDigestValue);
		
		if (!"fd622a3c4a2d4d72a32139542a5fc496".equals(client_id))
		{
			Map<String, String> rMap = new HashMap<>();
			rMap.put("response_code", "0");
			rMap.put("response_msg", "签名失败");
			rMap.put("signature", "");
			return rMap;
		}
		
		/*dataSign.setType(type);
		dataSign.setTimestamp(timestamp);
		dataSign.setFromClientId(from_client_id);
		dataSign.setClientId(client_id);
		dataSign.setSign(sign);
		dataSign.setCebName(ceb_name);
		dataSign.setBaseTransferCopCode(base_transfer_cop_code);
		dataSign.setDataToSign(toDigestValue);
		dataSign.setDigestValue("");
		dataSign.save();*/
		
		CompletableFuture<String> future = CompletableFuture.supplyAsync(()-> 
		{
			// 查询加签的数据
			try 
			{
				Socket socket = null;
				if (ceb_name.equals("CEB311"))
				{
					socket = CEB311SignSocketServer.getSocket();
				}
				else if (ceb_name.equals("CEB511"))
				{
					socket = CEB511SignSocketServer.getSocket();
				}
				else if (ceb_name.equals("CEB621"))
				{
					socket = CEB621SignSocketServer.getSocket();
				}
				
				if (null == socket) 
				{
					return null;
				}
				// 1.发送要加签的摘要
				socket.getOutputStream().write((toDigestValue).getBytes("UTF-8"));
				
				// 2.建立好连接之后,从加签客户端获取加签数据
		        InputStream inputStream = socket.getInputStream();
		        byte[] bytes = new byte[1024];
		        int len;
		        StringBuilder sb = new StringBuilder();
		        while ((len = inputStream.read(bytes)) != -1) {
		        	//注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8
		            sb.append(new String(bytes, 0, len, "UTF-8"));
		            if (sb.toString().contains(";end")) {
		            	break;
		            }
		        }
		        System.out.println("get message from client: " + sb);
		        return sb.toString().replace(";end", "");
			} 
			catch (IOException e) 
			{
				System.out.println("Socket发送数据失败." + e.toString());
				CEB311SignSocketServer.closeSocket();
			}
			return null;
		});
		
		String digestValue = future.join();
		System.out.println("digestValue=" + digestValue);
		
		if (null == digestValue) {
			Map<String, String> rMap = new HashMap<>();
			rMap.put("response_code", "0");
			rMap.put("response_msg", "签名失败");
			rMap.put("signature", "");
			return rMap;
		} else {
			Map<String, String> rMap = new HashMap<>();
			rMap.put("response_code", "1");
			rMap.put("response_msg", "签名成功");
			rMap.put("signature", digestValue);
			return rMap;
		}
	}
	
	/*private String getDigestValue(String xml)
	{
		@SuppressWarnings({"unchecked"})
		Map<String, String> rMap = (Map<String, String>)XmlUtils.parseStringXmlToMap(xml).get("Reference");
		return rMap.get("DigestValue");
	}*/
}
